home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 343_01 / edge.c < prev   
Text File  |  1991-04-18  |  18KB  |  743 lines

  1.  
  2.        /***********************************************
  3.        *
  4.        *       file d:\cips\edge.c
  5.        *
  6.        *       Functions: This file contains
  7.        *          detect_edges
  8.        *          setup_masks
  9.        *          get_edge_options
  10.        *          perform_convolution
  11.        *          quick_edge
  12.        *          fix_edges
  13.        *
  14.        *       Purpose:
  15.        *          These functions implement several
  16.        *          types of basic edge detection.
  17.        *
  18.        *       External Calls:
  19.        *          wtiff.c - does_not_exist
  20.        *                    round_off_image_size
  21.        *                    create_allocate_tiff_file
  22.        *                    write_array_into_tiff_image
  23.        *          tiff.c - read_tiff_header
  24.        *          rtiff.c - read_tiff_image
  25.        *          numcvrt.c - get_integer
  26.        *
  27.        *
  28.        *       Modifications:
  29.        *          27 January 1991 - created
  30.        *
  31.        *************************************************/
  32.  
  33. #include "d:\cips\cips.h"
  34.  
  35.  
  36.  
  37.  
  38.  
  39. short quick_mask[3][3] =  {
  40.        {-1,  0, -1},
  41.        { 0,  4,  0},
  42.        {-1,  0, -1} };
  43.  
  44.  
  45.    /***************************
  46.    *
  47.    *   Directions for the masks
  48.    *  3 2 1
  49.    *  4 x 0
  50.    *  5 6 7
  51.    *
  52.    ****************************/
  53.  
  54.    /* masks for kirsch operator */
  55. short kirsch_mask_0[3][3] =  {
  56.        { 5,  5,  5},
  57.        {-3,  0, -3},
  58.        {-3, -3, -3} };
  59.  
  60. short kirsch_mask_1[3][3] =  {
  61.        {-3,  5,  5},
  62.        {-3,  0,  5},
  63.        {-3, -3, -3} };
  64.  
  65. short kirsch_mask_2[3][3] =  {
  66.        {-3, -3,  5},
  67.        {-3,  0,  5},
  68.        {-3, -3,  5} };
  69.  
  70. short kirsch_mask_3[3][3] =  {
  71.        {-3, -3, -3},
  72.        {-3,  0,  5},
  73.        {-3,  5,  5} };
  74.  
  75. short kirsch_mask_4[3][3] =  {
  76.        {-3, -3, -3},
  77.        {-3,  0, -3},
  78.        { 5,  5,  5} };
  79.  
  80. short kirsch_mask_5[3][3] =  {
  81.        {-3, -3, -3},
  82.        { 5,  0, -3},
  83.        { 5,  5, -3} };
  84.  
  85. short kirsch_mask_6[3][3] =  {
  86.        { 5, -3, -3},
  87.        { 5,  0, -3},
  88.        { 5, -3, -3} };
  89.  
  90. short kirsch_mask_7[3][3] =  {
  91.        { 5,  5, -3},
  92.        { 5,  0, -3},
  93.        {-3, -3, -3} };
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.    /* masks for prewitt operator */
  101.  
  102. short prewitt_mask_0[3][3] =  {
  103.        { 1,  1,  1},
  104.        { 1, -2,  1},
  105.        {-1, -1, -1} };
  106.  
  107. short prewitt_mask_1[3][3] =  {
  108.        { 1,  1,  1},
  109.        { 1, -2, -1},
  110.        { 1, -1, -1} };
  111.  
  112. short prewitt_mask_2[3][3] =  {
  113.        { 1,  1, -1},
  114.        { 1, -2, -1},
  115.        { 1,  1, -1} };
  116.  
  117. short prewitt_mask_3[3][3] =  {
  118.        { 1, -1, -1},
  119.        { 1, -2, -1},
  120.        { 1,  1,  1} };
  121.  
  122. short prewitt_mask_4[3][3] =  {
  123.        {-1, -1, -1},
  124.        { 1, -2,  1},
  125.        { 1,  1,  1} };
  126.  
  127. short prewitt_mask_5[3][3] =  {
  128.        {-1, -1,  1},
  129.        {-1, -2,  1},
  130.        { 1,  1,  1} };
  131.  
  132. short prewitt_mask_6[3][3] =  {
  133.        {-1,  1,  1},
  134.        {-1, -2,  1},
  135.        {-1,  1,  1} };
  136.  
  137. short prewitt_mask_7[3][3] =  {
  138.        { 1,  1,  1},
  139.        {-1, -2,  1},
  140.        {-1, -1,  1} };
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.    /* masks for sobel operator */
  148.  
  149. short sobel_mask_0[3][3] =  {
  150.        { 1,  2,  1},
  151.        { 0,  0,  0},
  152.        {-1, -2, -1} };
  153.  
  154. short sobel_mask_1[3][3] =  {
  155.        { 2,  1,  0},
  156.        { 1,  0, -1},
  157.        { 0, -1, -2} };
  158.  
  159. short sobel_mask_2[3][3] =  {
  160.        { 1,  0, -1},
  161.        { 2,  0, -2},
  162.        { 1,  0, -1} };
  163. short sobel_mask_3[3][3] =  {
  164.        { 0, -1, -2},
  165.        { 1,  0, -1},
  166.        { 2,  1,  0} };
  167.  
  168. short sobel_mask_4[3][3] =  {
  169.        {-1, -2, -1},
  170.        { 0,  0,  0},
  171.        { 1,  2,  1} };
  172.  
  173. short sobel_mask_5[3][3] =  {
  174.        {-2, -1,  0},
  175.        {-1,  0,  1},
  176.        { 0,  1,  2} };
  177.  
  178. short sobel_mask_6[3][3] =  {
  179.        {-1,  0,  1},
  180.        {-2,  0,  2},
  181.        {-1,  0,  1} };
  182.  
  183. short sobel_mask_7[3][3] =  {
  184.        { 0,  1,  2},
  185.        {-1,  0,  1},
  186.        {-2, -1,  0} };
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.   /**************************************************
  194.   *
  195.   *   detect_edges(...
  196.   *
  197.   *   This function detects edges in an area of one
  198.   *   image and sends the result to another image
  199.   *   on disk.  It reads the input image from disk,
  200.   *   calls a convolution function, and then writes
  201.   *   the result out to disk.  If needed, it
  202.   *   allocates space on disk for the output image.
  203.   *
  204.   ***************************************************/
  205.  
  206.  
  207.  
  208.  
  209. detect_edges(in_name, out_name, the_image, out_image,
  210.              il, ie, ll, le, detect_type, threshold,
  211.              high)
  212.    char   in_name[], out_name[];
  213.    int    detect_type, high, il, ie,
  214.           ll, le, threshold;
  215.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  216.  
  217. {
  218.    int    i, j, k, length, width;
  219.    struct tiff_header_struct image_header;
  220.  
  221.  
  222.    if(does_not_exist(out_name)){
  223.       read_tiff_header(in_name, &image_header);
  224.       round_off_image_size(&image_header,
  225.                            &length, &width);
  226.       image_header.image_length = length*ROWS;
  227.       image_header.image_width  = width*COLS;
  228.       create_allocate_tiff_file(out_name, &image_header,
  229.                                 out_image);
  230.    }  /* ends if does_not_exist */
  231.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  232.  
  233.    read_tiff_header(in_name, &image_header);
  234.  
  235.    perform_convolution(the_image, out_image,
  236.                        detect_type, threshold,
  237.                        &image_header, high);
  238.  
  239.    fix_edges(out_image, 1);
  240.  
  241.    write_array_into_tiff_image(out_name, out_image,
  242.                                il, ie, ll, le);
  243. }  /* ends detect_edges */
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.      /**********************************************************
  252.      *
  253.      *   perform_convolution(...
  254.      *
  255.      *   This function performs convolution between the input
  256.      *   image and 8 3x3 masks.  The result is placed in
  257.      *   the out_image.
  258.      *
  259.      ********************************************************/
  260.  
  261. perform_convolution(image, out_image,
  262.                     detect_type, threshold,
  263.                     image_header, high)
  264.    short image[ROWS][COLS],
  265.          out_image[ROWS][COLS];
  266.    int   detect_type, high, threshold;
  267.    struct tiff_header_struct *image_header;
  268. {
  269.  
  270.    int a,
  271.        b,
  272.        i,
  273.        is_present,
  274.        j,
  275.        sum;
  276.  
  277.    short  mask_0[3][3],
  278.           mask_1[3][3],
  279.           mask_2[3][3],
  280.           mask_3[3][3],
  281.           mask_4[3][3],
  282.           mask_5[3][3],
  283.           mask_6[3][3],
  284.           mask_7[3][3],
  285.           max,
  286.           min,
  287.           new_hi,
  288.           new_low;
  289.  
  290.  
  291.    setup_masks(detect_type, mask_0, mask_1,
  292.                mask_2, mask_3, mask_4, mask_5,
  293.                mask_6, mask_7);
  294.  
  295.    new_hi  = 250;
  296.    new_low = 16;
  297.    if(image_header->bits_per_pixel == 4){
  298.        new_hi  = 10;
  299.        new_low = 3;
  300.    }
  301.  
  302.    min = 0;
  303.    max = 255;
  304.    if(image_header->bits_per_pixel == 4)
  305.       max = 16;
  306.  
  307.      /* clear output image array */
  308.    for(i=0; i<ROWS; i++)
  309.       for(j=0; j<COLS; j++)
  310.          out_image[i][j] = 0;
  311.  
  312.    printf("\n ");
  313.  
  314.    for(i=1; i<ROWS-1; i++){
  315.       if( (i%10) == 0) printf("%3d", i);
  316.       for(j=1; j<COLS-1; j++){
  317.  
  318.  
  319.          /* Convolve for all 8 directions */
  320.  
  321.          /* 0 direction */
  322.  
  323.       sum = 0;
  324.       for(a=-1; a<2; a++){
  325.          for(b=-1; b<2; b++){
  326.             sum = sum + image[i+a][j+b] *
  327.                   mask_0[a+1][b+1];
  328.          }
  329.       }
  330.          if(sum > max) sum = max;
  331.          if(sum < 0)   sum = 0;
  332.       out_image[i][j]   = sum;
  333.  
  334.  
  335.          /* 1 direction */
  336.  
  337.       sum = 0;
  338.       for(a=-1; a<2; a++){
  339.          for(b=-1; b<2; b++){
  340.             sum = sum + image[i+a][j+b] * mask_1[a+1][b+1];
  341.          }
  342.       }
  343.          if(sum > max) sum = max;
  344.          if(sum < 0)   sum = 0;
  345.       out_image[i][j]   = sum;
  346.  
  347.  
  348.          /* 2 direction */
  349.  
  350.       sum = 0;
  351.       for(a=-1; a<2; a++){
  352.          for(b=-1; b<2; b++){
  353.             sum = sum + image[i+a][j+b] * mask_2[a+1][b+1];
  354.          }
  355.       }
  356.          if(sum > max) sum = max;
  357.          if(sum < 0)   sum = 0;
  358.       out_image[i][j]   = sum;
  359.  
  360.  
  361.          /* 3 direction */
  362.  
  363.       sum = 0;
  364.       for(a=-1; a<2; a++){
  365.          for(b